﻿using Microsoft.VisualBasic;
using System.IO;
using System.Collections;
using BaseClasses;
using BaseClasses.Data;
using BaseClasses.Utils;
using System;
namespace EnGasAdoAPP.Data
{

    /// <summary>
    /// The FormulaUtils class contains a set of functions that are available
    /// in the Formula editor. You can specify any of these functions after
    /// the = sign.
    /// For example, you can say:
    /// = IsEven(32)
    /// These functions throw an exception on an error. The formula evaluator
    /// catches this exception and returns the error string to the user interface.
    ///
    /// All of the functions operate as a Decimal. The Decimal data type is better
    /// then Double or Single since it provides a more accurate value as compared to
    /// Double, and a larger value as compared to a Single. All integers, doubles, etc.
    /// are converted to Decimals as part of these functions.
    ///
    /// Function names are not case sensitive. So you can use ROUND, Round, round, etc.
    ///
    /// </summary>
    /// <remarks></remarks>
    public class BaseFormulaUtils
    {
        #region "DataSource Lookup Functions"
        public static object Lookup(DataSource dataSourceName, object rowNumber, object id, object idColumn, object valueColumn)
        {
            return dataSourceName.Lookup(rowNumber, id, idColumn, valueColumn);

        }

        public static string Lookup(DataSource dataSourceName, object id, string format)
        {
            object val = dataSourceName.Lookup(null, id, null, null);
            if (val == null)
            {
                val = "";
            }
            return BaseFormulaUtils.Format(val, format);

        }

        public static string Lookup(DataSource dataSourceName, object id)
        {
            object val = dataSourceName.Lookup(null, id, null, null);
            if (val == null)
            {
                val = "";
            }
            return BaseFormulaUtils.Format(val, "");

        }

        #endregion

        #region "Information Functions"

        /// <summary>
        /// Check if the number is Even or not. 
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">Number to be checked</param>
        /// <returns>True if the input is even, False otherwise.</returns>
        public static bool IsEven(object val)
        {
            decimal valDecimal = 0;
            try
            {
                valDecimal = StringUtils.ParseDecimal(val);
                return (valDecimal % 2 == 0);
            }
            catch (Exception ex)
            {
                throw new Exception("ISEVEN(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Check if the input is odd or not
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">Number to be checked</param>
        /// <returns>True if the input is odd, False otherwise.</returns>
        public static bool IsOdd(object val)
        {
            decimal valDecimal = 0;
            try
            {
                valDecimal = StringUtils.ParseDecimal(val);
                return (valDecimal % 2 != 0);
            }
            catch (Exception ex)
            {
                throw new Exception("ISODD(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Check if the input is a number or not
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">Number to be checked</param>
        /// <returns>True if the input is a number, False otherwise.</returns>
        public static bool IsNumber(object val)
        {
            decimal valDecimal = 0;
            try
            {
                valDecimal = StringUtils.ParseDecimal(val);
                // If we are successfully parsing the number, then return True
                return true;
            }
            catch
            {
            // Ignore exception, just fall through and return false
            }
            return false;
        }

        /// <summary>
        /// Check if the input is logical or not
        /// The value can be specified as a decimal value (e.g., 37.48), 
        /// as a string (“True”), as a Boolean (e.g., True), as an expression (e.g., 1+1=2), 
        /// or as the value of a variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">Value to be checked</param>
        /// <returns>True if the input is a boolean, False otherwise.</returns>
        public static bool IsLogical(object val)
        {
            bool valBoolean = false;
            try
            {
                valBoolean = Convert.ToBoolean(val);
                // If we are able to successfully convert the value, then return True
                return true;
            }
            catch
            {
            // Ignore exception, just fall through and return false
            }
            return false;
        }

        /// <summary>
        /// Check if the input is null or not
        /// The value can be specified as a decimal value (e.g., 37.48), as a string (“True”),
        /// as an expression (e.g., 1+1=2), or as the value of a variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">Value to be checked</param>
        /// <returns>True if the input is null</returns>
        public static bool IsNull(object val)
        {
            // If val is nothing, then return True
            if (val == null)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Check if the value entered is blank or not. A NULL value is considered blank too.
        /// The value can be specified as a decimal value (e.g., 37.48), as a string (“  ”), 
        /// as an expression (e.g., 1+1=2), or as the value of a variable (e.g, ShippedDate).
        /// </summary>
        /// <param name="val">Value to be checked</param>
        /// <returns>True if the input is blank</returns>
        public static bool IsBlank(object val)
        {
            if (val == null) return true;

            if (object.ReferenceEquals(val.GetType(), typeof(string)) && ((string)val).Trim().Length == 0) return true;

            return false;
        }

        /// <summary>
        /// Check if the value entered is a text or not
        /// The value can be specified as a decimal value (e.g., 37.48), as a string (“  ”), 
        /// as an expression (e.g., 1+1=2), or as the value of a variable (e.g, ShippedDate).
        /// </summary>
        /// <param name="val">Value to be checked</param>
        /// <returns>True if the input is text</returns>
        public static bool IsText(object val)
        {
            if (val == null) return false;

            if (object.ReferenceEquals(val.GetType(), typeof(string))) return true;

            return false;
        }

        #endregion

        #region "Mathematical Functions"

        /// <summary>
        /// Calculate the absolute value of the argument passed
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The input whose absolute value is to be found.</param>
        /// <returns>The absolute value of the number.</returns>
        public static decimal Abs(object val)
        {
            try
            {
                return Math.Abs(StringUtils.ParseDecimal(val));
            }
            catch (Exception ex)
            {
                throw new Exception("ABS(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the ceiling value of the argument passed
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The input whose ceiling value is to be calculated.</param>
        /// <returns>The ceiling value of the number.</returns>
        public static decimal Ceiling(object val)
        {
            try
            {
                return Math.Ceiling(StringUtils.ParseDecimal(val));
            }
            catch (Exception ex)
            {
                throw new Exception("CEILING(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculates the exponential value of the input
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The input whose exponential value is to be calculated</param>
        /// <returns>
        /// The exponential value of the input
        /// </returns>
        public static decimal Exp(object val)
        {
            Double valDouble = 0;
            try
            {
                valDouble = Convert.ToDouble(StringUtils.ParseDecimal(val));
                return Convert.ToDecimal(Math.Exp(valDouble));
            }
            catch (Exception ex)
            {
                throw new Exception("EXP(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculates the floor value of the input
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The input whose floor value is to be calculated</param>
        /// <returns>
        /// The floor value of the input
        /// </returns>
        public static decimal Floor(object val)
        {
            try
            {
                return Math.Floor(StringUtils.ParseDecimal(val));
            }
            catch (Exception ex)
            {
                throw new Exception("FLOOR(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculates the mod value of the division 
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="dividend">The dividend</param>
        /// <param name="divisor">The divisor</param>
        /// <returns>
        /// The mod value of the division.
        /// </returns>
        public static decimal Modulus(object dividend, object divisor)
        {
            decimal dividendDecimal = 0;
            decimal divisorDecimal = 0;
            try
            {
                dividendDecimal = StringUtils.ParseDecimal(dividend);
                divisorDecimal = StringUtils.ParseDecimal(divisor);
                return dividendDecimal % divisorDecimal;
            }
            catch (Exception ex)
            {
                throw new Exception("MODULUS(" + GetStr(dividendDecimal) + ", " + GetStr(divisorDecimal) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the value of a variable raised to the power of the other.
        /// The number can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val1">The base</param>
        /// <param name="val2">The power</param>
        /// <returns>
        /// The val1 raised to the power of val2
        /// </returns>
        public static decimal Power(object val1, object val2)
        {
            Double val1Double = 0;
            Double val2Double = 0;
            try
            {
                val1Double = Convert.ToDouble(StringUtils.ParseDecimal(val1));
                val2Double = Convert.ToDouble(StringUtils.ParseDecimal(val2));
                return Convert.ToDecimal(Math.Pow(val1Double, val2Double));
            }
            catch (Exception ex)
            {
                throw new Exception("POWER(" + GetStr(val1) + ", " + GetStr(val2) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Return the value of PI as a Decimal.
        /// </summary>
        public static decimal Pi()
        {
            return Convert.ToDecimal(Math.PI);
        }

        /// <summary>
        /// Calculate the quotient of the division 
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val1">The dividend of the division</param>
        /// <param name="val2">The divisor of the division</param>
        /// <returns>
        /// The quotient of the division.
        /// </returns>
        public static decimal Quotient(object dividend, object divisor)
        {
            try
            {
                return Convert.ToDecimal(Math.Ceiling(StringUtils.ParseDecimal(dividend) / StringUtils.ParseDecimal(divisor)));
            }
            catch (Exception ex)
            {
                throw new Exception("QUOTIENT(" + GetStr(dividend) + ", " + GetStr(divisor) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Round value up to the specified number of decimal places
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="number">Number to be rounded</param>
        /// <param name="numberOfDigits">Number of decimals to be rounded upto</param>
        /// <returns>The rounded up value.</returns>
        public static decimal Round(object number, object numberOfDigits)
        {
            try
            {
                return Math.Round(StringUtils.ParseDecimal(number), (int)(numberOfDigits));
            }
            catch (Exception ex)
            {
                throw new Exception("ROUND(" + GetStr(number) + ", " + GetStr(numberOfDigits) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the square root value of the input
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The argument whose square root is to be calculated</param>
        /// <returns>The square root.</returns>
        public static decimal Sqrt(object val)
        {
            Double valDouble = 0;
            try
            {
                valDouble = Convert.ToDouble(StringUtils.ParseDecimal(val));
                return Convert.ToDecimal(Math.Sqrt(valDouble));
            }
            catch (Exception ex)
            {
                throw new Exception("SQRT(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the truncated value of the input
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The argument whose truncated value is to be calculated</param>
        /// <returns>The truncated value.</returns>
        public static decimal Trunc(object val)
        {
            try
            {
                return Convert.ToDecimal(Math.Truncate(StringUtils.ParseDecimal(val)));
            }
            catch (Exception ex)
            {
                throw new Exception("TRUNC(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the logarithmic value to the specified base
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val1">The argument whose log value is to be calculated</param>
        /// <param name="val2">The value which would act as a base</param>
        /// <returns>The log value</returns>
        public static decimal Log(object val1, object val2)
        {
            Double val1Double = 0;
            Double val2Double = 0;
            try
            {
                val1Double = Convert.ToDouble(StringUtils.ParseDecimal(val1));
                val2Double = Convert.ToDouble(StringUtils.ParseDecimal(val2));
                return Convert.ToDecimal(Math.Log(val1Double, val2Double));
            }
            catch (Exception ex)
            {
                throw new Exception("LOG(" + GetStr(val1) + ", " + GetStr(val2) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Calculate the logarithmic value to the base 10
        /// The number(s) can be specified as an integer (e.g., 37), a decimal 
        /// value (e.g., 37.48), as a string with an optional currency symbol and 
        /// separators ("1,234.56", "$1,234.56"), or as the value of a 
        /// variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="val">The argument whose log value is to be calculated</param>
        /// <returns>The log value.</returns>
        public static decimal Log(object val)
        {
            Double valDouble = 0;
            try
            {
                valDouble = Convert.ToDouble(StringUtils.ParseDecimal(val));
                return Convert.ToDecimal(Math.Log10(valDouble));
            }
            catch (Exception ex)
            {
                throw new Exception("LOG(" + GetStr(val) + "): " + ex.Message);
            }
        }

        #endregion

        #region "Boolean Functions"

        /// <summary>
        /// Calculate the AND value of the input array
        /// The value(s) can be specified as a decimal value (e.g., 37.48), 
        /// as a string (“True”), as a Boolean (e.g., True), as an expression (e.g., 1+1=2), 
        /// or as the value of a variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="args">The array of booleans whose AND value is to be calculated</param>
        /// <returns>The and value.</returns>
        public static bool And1(params object[] args)
        {
            bool andValue = true;
            // Iterate the loop to get the individual values from the group of parameters
            foreach (object booleanValue in args)
            {
                if (booleanValue != null)
                {
                    try
                    {
                        andValue = andValue && Convert.ToBoolean(booleanValue.ToString());
                        if (andValue == false) return andValue;
                    }
                    catch
                    {
                        //if a value is non-boolean, we will ignore this value.
                    }
                }
            }
            return andValue;
        }

        /// <summary>
        /// Calculate the OR value of the input array
        /// The value(s) can be specified as a decimal value (e.g., 37.48), 
        /// as a string (“True”), as a Boolean (e.g., True), as an expression (e.g., 1+1=2), 
        /// or as the value of a variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="args">The array of booleans whose OR value is to be calculated</param>
        /// <returns>The or value.</returns>
        public static bool Or1(params object[] args)
        {
            bool orValue = false;
            // Iterate the loop to get the individual values from the group of parameters
            foreach (object booleanValue in args)
            {
                if (booleanValue != null)
                {
                    try
                    {
                        orValue = orValue || Convert.ToBoolean(booleanValue);
                        if (orValue == true) return orValue;
                    }
                    catch
                    {
                        //if a value is non-boolean, we will ignore this value.
                    }
                }
            }
            return orValue;
        }

        /// <summary>
        /// Calculate the NOT value of the specified boolean value
        /// The value(s) can be specified as a decimal value (e.g., 37.48), 
        /// as a string (“True”), as a Boolean (e.g., True), as an expression (e.g., 1+1=2), 
        /// or as the value of a variable (e.g, UnitPrice).
        /// </summary>
        /// <param name="value">The boolean value whose NOT is to be determined</param>
        /// <returns>The not value.</returns>
        public static bool Not1(object value)
        {
            try
            {
                return !Convert.ToBoolean(value);
            }
            catch (Exception ex)
            {
                throw new Exception("NOT1(" + GetStr(value) + "): " + ex.Message);
            }
        }
        #endregion

        #region "String Functions"

        /// <summary>
        /// Return a character for the corresponding ascii value
        /// </summary>
        /// <param name="val">Ascii Value</param>
        /// <returns>Charcter for the corresponding ascii value</returns>
        public static char Character(object val)
        {
            try
            {
                return Convert.ToChar(val);
            }
            catch (Exception ex)
            {
                throw new Exception("CHARACTER(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Check if two strings are exactly same or not
        /// </summary>
        /// <param name="val1">1st String</param>
        /// <param name="val2">2nd String</param>
        /// <returns>True if the two strings are exactly same else returns false</returns>
        public static bool Exact(object val1, object val2)
        {
            try
            {
                val1 = GetStr(val1);
                val2 = GetStr(val2);
                if (val1.Equals(val2))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("EXACT(" + GetStr(val1) + ", " + GetStr(val2) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Finds the index of the occurrence of the 1st string in the 2nd string specified
        /// </summary>
        /// <param name="val1">String to be searched</param>
        /// <param name="val2">String to be searched in</param>
        /// <returns>The index of the occurrence of the 1st string in the 2nd string and -1 if the string not found</returns>
        public static int Find(object val1, object val2)
        {
            string val1String = string.Empty;
            string val2String = string.Empty;
            try
            {
                if (val1 != null) val1String = val1.ToString();
                if (val2 != null) val2String = val2.ToString();

                return val2String.IndexOf(val1String, 0);
            }
            catch (Exception ex)
            {
                throw new Exception("FIND(" + GetStr(val1) + ", " + GetStr(val2) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Find the index of the occurrence of the 1st string in the 2nd string,
        /// the search starts after a specified start position
        /// </summary>
        /// <param name="val1">String to be searched</param>
        /// <param name="val2">String to be searched in</param>
        /// <param name="index">The position after which the search should start</param>
        /// <returns>The index of the occurrence of the 1st string in the 2nd string and -1 if the string is not found</returns>
        public static int Find(object val1, object val2, int index)
        {
            string val1String = string.Empty;
            string val2String = string.Empty;
            try
            {
                if (val1 != null) val1String = val1.ToString();
                if (val2 != null) val2String = val2.ToString();

                return val2String.IndexOf(val1String, index);
            }
            catch (Exception ex)
            {
                throw new Exception("FIND(" + GetStr(val1) + ", " + GetStr(val2) + ", " + index + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns the string from left till the index mentioned
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <param name="length">The length of string to be returned</param>
        /// <returns>The string of specified length from the start</returns>
        public static string Left(object str, int length)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();

                return inputString.Substring(0, length);
            }
            catch (Exception ex)
            {
                throw new Exception("LEFT(" + GetStr(str) + ", " + length + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns the string from right till the index mentioned
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <param name="length">The length of string to be returned</param>
        /// <returns>The string of specified length from the end</returns>
        public static string Right(object str, int length)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                
                return inputString.Substring(inputString.Length - length, length);
            }
            catch (Exception ex)
            {
                throw new Exception("RIGHT(" + GetStr(str) + ", " + length + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns the left most character of the string
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The first character of string</returns>
        public static string Left(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.Substring(0, 1);
            }
            catch (Exception ex)
            {
                throw new Exception("LEFT(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns the right most character of the string
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The last character of a string</returns>
        public static string Right(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.Substring(inputString.Length - 1, 1);
            }
            catch (Exception ex)
            {
                throw new Exception("RIGHT(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns the length of the string
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The length of the string</returns>
        public static int Len(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.Length;
            }
            catch (Exception ex)
            {
                throw new Exception("LEN(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Converts the string to lower case 
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The string which is lower case</returns>
        public static string Lower(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.ToLower();
            }
            catch (Exception ex)
            {
                throw new Exception("LOWER(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Converts the string to upper case
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The string which is upper case</returns>
        public static string Upper(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.ToUpper();
            }
            catch (Exception ex)
            {
                throw new Exception("UPPER(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the substring from the specified index and of specified length
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <param name="startIndex">The start index of retrieval</param>
        /// <param name="length">Length of the string to be retrieved</param>
        /// <returns>The substring</returns>
        public static string Mid(object str, int startIndex, int length)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.Substring(startIndex, length);
            }
            catch (Exception ex)
            {
                throw new Exception("MID(" + GetStr(str) + ", " + startIndex + ", " + length + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the substring from the specified index and of specified length
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <param name="startIndex">The start index of retrieval</param>
        /// <param name="length">Length of the string to be retrieved</param>
        /// <returns>The substring</returns>
        public static string Substring(object str, int startIndex, int length)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                return inputString.Substring(startIndex, length);
            }
            catch (Exception ex)
            {
                throw new Exception("SUBSTRING(" + GetStr(str) + ", " + startIndex + ", " + length + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the substring from the specified index till the end of the string
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <param name="startIndex">The start index of retrieval</param>
        /// <returns>The substring</returns>
        public static string Substring(object str, int startIndex)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                // As we are using a 1 based indexing we are using .Length 
                // which returns the exact length
                return inputString.Substring(startIndex, inputString.Length - startIndex);
            }
            catch (Exception ex)
            {
                throw new Exception("SUBSTRING(" + GetStr(str) + ", " + startIndex + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the substring from the specified index till the end of the string
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>The Capitalized string</returns>
        public static string Capitalize(object str)
        {
            string inputString = string.Empty;
            try
            {
                if (str != null) inputString = str.ToString();
                // As we are using a 1 based indexing we are using .Length 
                // which returns the exact length
                return inputString.Substring(0, 1).ToUpper() + inputString.Substring(1, inputString.Length - 1);
            }
            catch (Exception ex)
            {
                throw new Exception("CAPITALIZE(" + GetStr(str) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Replaces the specified part of a string with a new string
        /// </summary>
        /// <param name="oldString">String to be operated upon</param>
        /// <param name="startIndex">The start index of the part to be replaced</param>
        /// <param name="length">The length of the part be replaced</param>
        /// <param name="newString">The new string which replaces the old string.</param>
        /// <returns>The string which is upper case</returns>
        public static string Replace(object oldString, int startIndex, int length, object newString)
        {
            string inputString = string.Empty;
            try
            {
                if (oldString != null) inputString = oldString.ToString();
                // We are using a 1 based indexing in this function
                return inputString.Substring(0, startIndex) + newString.ToString() + inputString.Substring(startIndex + length);
            }
            catch (Exception ex)
            {
                throw new Exception("REPLACE(" + GetStr(oldString) + ", " + startIndex + ", " + length + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Repeats the text specified number of times the specified part of a string with a new string
        /// </summary>
        /// <param name="text">Text to be operated</param>
        /// <param name="numberOfTimes">The number of times text is to be repeated</param>
        /// <returns>The string with repeatetive text in it</returns>
        public static string Rept(object text, int numberOfTimes)
        {
            string textStr = string.Empty;
            string finalString = string.Empty;
            int i = 0;
            // We are using a 1 based indexing in this function
            if (text != null) textStr = text.ToString();
            try
            {
                for (i = 0; i <= numberOfTimes - 1; i++)
                {
                    finalString = finalString + textStr;
                }
                return finalString;
            }
            catch (Exception ex)
            {
                throw new Exception("REPT(" + GetStr(text) + ", " + numberOfTimes + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Concatenates the arguments in the array
        /// </summary>
        /// <param name="args">Array of arguments</param>
        /// <returns>Concatenated string</returns>
        public static string Concatenate(params object[] args)
        {
            string finalString = string.Empty;
            // We are using a 1 based indexing in this function
            try
            {
                foreach (object str in args)
                {
                    if (str != null) finalString = finalString + str.ToString();
                }
                return finalString;
            }
            catch (Exception ex)
            {
                throw new Exception("CONCATENATE(" + GetStr(args) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Trims the leading and trailing spaces
        /// </summary>
        /// <param name="str">String to be operated upon</param>
        /// <returns>Trimmed string</returns>
        public static string Trim(object str)
        {
            try
            {
                string finalString = string.Empty;
                if (str != null) finalString = str.ToString().Trim();
                return finalString;
            }
            catch (Exception ex)
            {
                throw new Exception("TRIM(" + GetStr(str) + "): " + ex.Message);
            }
        }
        #endregion

        #region "DateTime Functions"

        /// <summary>
        /// Retrieves the hours from the date
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The hour part of the date and if date is empty string then returns today's hours</returns>
        public static decimal Hour(object valDate)
        {
            DateTime finalDate = new DateTime();
            try
            {
                if (!DateTime.TryParse(valDate.ToString(), out finalDate)) return DateTime.Now.Hour;
                return finalDate.Hour;
            }
            catch (Exception ex)
            {
                throw new Exception("HOUR(" + GetStr(valDate) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the minutes from the date
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The minutes part of the date and if date is empty string then returns today's hours</returns>
        public static decimal Minute(object valDate)
        {
            DateTime finalDate = new DateTime();
            try
            {
                if (!DateTime.TryParse(valDate.ToString(), out finalDate)) return DateTime.Now.Minute;
                return finalDate.Minute;
            }
            catch (Exception ex)
            {
                throw new Exception("MINUTE(" + GetStr(valDate) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the years from the date
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The years part of the date and if date is empty string then returns today's hours</returns>
        public static decimal Year(object valDate)
        {
            DateTime finalDate = new DateTime();
            try
            {
                if (!DateTime.TryParse(valDate.ToString(), out finalDate)) return DateTime.Now.Year;
                return finalDate.Year;
            }
            catch (Exception ex)
            {
                throw new Exception("MINUTE(" + GetStr(valDate) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the month from the date
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The month part of the date and if date is empty string then returns this month</returns>
        public static decimal Month(object valDate)
        {
            DateTime finalDate = new DateTime();
            try
            {
                if (!DateTime.TryParse(valDate.ToString(), out finalDate)) return DateTime.Now.Month;
                return finalDate.Month;
            }
            catch (Exception ex)
            {
                throw new Exception("MONTH(" + GetStr(valDate) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Retrieves the seconds from the date
        /// </summary>
        /// <param name="val">The date to be operated upon</param>
        /// <returns>The seconds part of the date and if date is empty string then returns seconds now</returns>
        public static decimal Second(object valDate)
        {
            DateTime finalDate = new DateTime();
            try
            {
                if (!DateTime.TryParse(valDate.ToString(), out finalDate)) return DateTime.Now.Second;
                return finalDate.Second;
            }
            catch (Exception ex)
            {
                throw new Exception("SECOND(" + GetStr(valDate) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns a datevalue specifying the hours minutes and seconds
        /// </summary>
        /// <param name="val">The date to be operated upon</param>
        /// <returns>The seconds part of the date and if date is empty string then returns seconds now</returns>
        public static DateTime Time1(object valHour, object valMinute, object valSecond)
        {

            DateTime finalDate;
            finalDate = DateTime.Today;

            try
            {
                finalDate = finalDate.AddHours(Convert.ToInt32(valHour));
                finalDate = finalDate.AddMinutes(Convert.ToInt32(valMinute));
                finalDate = finalDate.AddSeconds(Convert.ToInt32(valSecond));

                return finalDate;
            }
            catch (Exception ex)
            {
                throw new Exception("TIME1(" + GetStr(valHour) + ", " + GetStr(valMinute) + ", " + GetStr(valSecond) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Returns today's date
        /// </summary>
        /// <returns>Today's date</returns>
        public static DateTime Now()
        {
            return DateTime.Now;
        }

        /// <summary>
        /// Returns today's date
        /// </summary>
        /// <returns>Today's date</returns>
        public static DateTime Today()
        {
            return DateTime.Today;
        }

        /// <summary>
        /// Retrieves yesterday's date
        /// </summary>
        /// <returns>Yesterday's date</returns>
        public static DateTime Yesterday()
        {
            return DateTime.Today.AddDays(-1);
        }

        /// <summary>
        /// Retrieve the date of start of the week
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The start date of the week</returns>
        public static DateTime StartOfWeek(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(0 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 0, 0, 0);
        }

        /// <summary>
        /// Retrieve the date of end of the week
        /// </summary>
        /// <param name="valDate">The date to be operated upon</param>
        /// <returns>The end date of the week</returns>
        public static DateTime EndOfWeek(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(6 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 23, 59, 59);
        }

        /// <summary>
        /// Retrieve the start date of the current week
        /// </summary>
        /// <returns>The start date of the current week</returns>
        public static DateTime StartOfCurrentWeek()
        {
            DateTime inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(0 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 0, 0, 0);
        }

        /// <summary>
        /// Retrieve the end date of the current week
        /// </summary>
        /// <returns>The end date of the current week</returns>
        public static DateTime EndOfCurrentWeek()
        {
            DateTime inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(6 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 23, 59, 59);
        }

        /// <summary>
        /// Retrieve the start date of the previous week
        /// </summary>
        /// <returns>The start date of the previous week</returns>
        public static DateTime StartOfLastWeek()
        {
            DateTime inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(-7 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 0, 0, 0);
        }

        /// <summary>
        /// Retrieve the end date of the previous week
        /// </summary>
        /// <returns>The end date of the previous week</returns>
        public static DateTime EndOfLastWeek()
        {
            DateTime inputDate = DateTime.Today;
            inputDate = inputDate.AddDays(-1 - Convert.ToDouble(inputDate.DayOfWeek));
            return new DateTime(inputDate.Year, inputDate.Month, inputDate.Day, 23, 59, 59);
        }

        /// <summary>
        /// Retrieve the start date of the month for the date passed
        /// </summary>
        /// <param name="valDate">The date whose start date of month is to be found</param>
        /// <returns>The start date of the month</returns>
        public static DateTime StartOfMonth(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            DateTime startDate = new DateTime(inputDate.Year, inputDate.Month, 1);
            return startDate;
        }

        /// <summary>
        /// Retrieve the end date of the month for the date passed
        /// </summary>
        /// <param name="valDate">The date whose end date of month is to be found</param>
        /// <returns>The end date of the month</returns>
        public static DateTime EndOfMonth(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            DateTime endDate = inputDate.AddMonths(1);
            endDate = new DateTime(endDate.Year, endDate.Month, 1, 23, 59, 59).AddDays(-1);
            return endDate;
        }

        /// <summary>
        /// Retrieve the start date of the current month
        /// </summary>
        /// <returns>The start date of the current month</returns>
        public static DateTime StartOfCurrentMonth()
        {
            DateTime startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
            return startDate;
        }

        /// <summary>
        /// Retrieve the end date of the current month
        /// </summary>
        /// <returns>The end date of the current month</returns>
        public static DateTime EndOfCurrentMonth()
        {
            DateTime endDate = DateTime.Today.AddMonths(1);
            endDate = new DateTime(endDate.Year, endDate.Month, 1, 23, 59, 59).AddDays(-1);
            return endDate;
        }

        /// <summary>
        /// Retrieve the start date of the last month
        /// </summary>
        /// <returns>The start date of the last month</returns>
        public static DateTime StartOfLastMonth()
        {
            DateTime prevMonthDate = DateTime.Today.AddMonths(-1);
            return new DateTime(prevMonthDate.Year, prevMonthDate.Month, 1);
        }

        /// <summary>
        /// Retrieve the end date of the last month
        /// </summary>
        /// <returns>The end date of the last month</returns>
        public static DateTime EndOfLastMonth()
        {
            DateTime endDate = DateTime.Today;
            endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 23, 59, 59);
            endDate = endDate.AddDays(-1);
            return endDate;
        }

        /// <summary>
        /// Retrieve the start date of the quarter for the date passed
        /// </summary>
        /// <param name="valDate">The date whose start date of quarter is to be found</param>
        /// <returns>The end date of the quarter</returns>
        public static DateTime StartOfQuarter(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            int quarter = (inputDate.Month - 1) / 3 + 1;
            DateTime startQuarterDate = new DateTime(inputDate.Year, 3 * quarter - 2, 1);
            return startQuarterDate;
        }

        /// <summary>
        /// Retrieve the end date of the quarter for the date passed
        /// </summary>
        /// <param name="valDate">The date whose end date of quarter is to be found</param>
        /// <returns>The end date of the quarter</returns>
        public static DateTime EndOfQuarter(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            int quarter = (inputDate.Month - 1) / 3 + 1;
            DateTime quarterLastDate = new DateTime(inputDate.Year, 3 * quarter, 1, 23, 59, 59).AddMonths(1).AddDays(-1);
            return quarterLastDate;
        }

        /// <summary>
        /// Retrieve the start date of the current quarter
        /// </summary>
        /// <returns>The start date of the current quarter</returns>
        public static DateTime StartOfCurrentQuarter()
        {
            DateTime dateToday = DateTime.Today;
            int currQuarter = (DateTime.Today.Month - 1) / 3 + 1;
            DateTime dtFirstDay = new DateTime(DateTime.Today.Year, 3 * currQuarter - 2, 1);
            return dtFirstDay;
        }

        /// <summary>
        /// Retrieve the end date of the current quarter
        /// </summary>
        /// <returns>The end date of the current quarter</returns>
        public static DateTime EndOfCurrentQuarter()
        {
            DateTime dateToday = DateTime.Today;
            int currQuarter = (DateTime.Today.Month - 1) / 3 + 1;
            DateTime quarterLastDate = new DateTime(DateTime.Today.Year, 3 * currQuarter, 1, 23, 59, 59).AddMonths(1).AddDays(-1);
            return quarterLastDate;
        }

        /// <summary>
        /// Retrieve the start date of the last quarter
        /// </summary>
        /// <returns>The start date of the last quarter</returns>
        public static DateTime StartOfLastQuarter()
        {
            int currQuarter = (DateTime.Today.Month - 1) / 3 + 1;
            DateTime lastQuarterStartDate = new DateTime(DateTime.Today.Year, 3 * currQuarter - 2, 1).AddMonths(-3);
            return lastQuarterStartDate;
        }

        /// <summary>
        /// Retrieve the end date of the last quarter
        /// </summary>
        /// <returns>The end date of the last quarter</returns>
        public static DateTime EndOfLastQuarter()
        {
            int currQuarter = (DateTime.Today.Month - 1) / 3 + 1;
            DateTime lastQuarterEndDate = new DateTime(DateTime.Today.Year, 3 * currQuarter - 2, 1, 23, 59, 59).AddDays(-1);
            return lastQuarterEndDate;
        }

        /// <summary>
        /// Retrieve the start date of the year for the date passed
        /// </summary>
        /// <param name="valDate">The date whose start date of year is to be found</param>
        /// <returns>The start date of the year</returns>
        public static DateTime StartOfYear(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            DateTime dtFirstDate = new DateTime(inputDate.Year, 1, 1);
            return dtFirstDate;
        }

        /// <summary>
        /// Retrieve the end date of the year for the date passed
        /// </summary>
        /// <returns>The end date of the year</returns>
        public static DateTime EndOfYear(object valDate)
        {
            DateTime inputDate = DateTime.Today;
            if (!DateTime.TryParse(valDate.ToString(), out inputDate)) inputDate = DateTime.Today;
            DateTime dtLastDate = new DateTime(inputDate.Year, 12, 31, 23, 59, 59);
            return dtLastDate;
        }

        /// <summary>
        /// Retrieve the start date of the current year
        /// </summary>
        /// <returns>The start date of the current year</returns>
        public static DateTime StartOfCurrentYear()
        {
            DateTime dtFirstDay = new DateTime(DateTime.Today.Year, 1, 1);
            return dtFirstDay;
        }

        /// <summary>
        /// Retrieve the end date of the current year
        /// </summary>
        /// <returns>The end date of the current year</returns>
        public static DateTime EndOfCurrentYear()
        {
            DateTime dtLastDay = new DateTime(DateTime.Today.Year, 12, 31, 23, 59, 59);
            return dtLastDay;
        }

        /// <summary>
        /// Retrieve the start date of the last year
        /// </summary>
        /// <returns>The start date of the last year</returns>
        public static DateTime StartOfLastYear()
        {
            DateTime dtFirstDay = new DateTime(DateTime.Today.Year - 1, 1, 1);
            return dtFirstDay;
        }

        /// <summary>
        /// Retrieve the end date of the last year
        /// </summary>
        /// <returns>The end date of the last year</returns>
        public static DateTime EndOfLastYear()
        {
            DateTime dtFirstDay = new DateTime(DateTime.Today.Year - 1, 12, 31, 23, 59, 59);
            return dtFirstDay;
        }

        #endregion

        #region "Format Functions"

        /// <summary>
        /// Formats the arguments according to the format string
        /// </summary>
        /// <param name="val">The value to be formatted</param>
        /// <param name="formatString">The format string needed to specify the format type</param>
        /// <returns>The formatted string</returns>
        public static string Format(object val, string formatString)
        {
            decimal valDecimal = 0;
            DateTime valDate = DateTime.Today;
            if (val == null)
            {
                return string.Empty;
            }

            try
            {

                try
                {
                    valDecimal = StringUtils.ParseDecimal(val);
                    return valDecimal.ToString(formatString);
                }
                catch
                {
                // Ignore
                }

                if (DateTime.TryParse(val.ToString(), out valDate))
                {
                    return valDate.ToString(formatString);
                }

                return StringUtils.ParseDecimal(val).ToString(formatString);
            }
            catch
            {
                return val.ToString();
            }
        }
        #endregion

        #region "Parse Functions"
        /// <summary>
        /// Converts the object to its Decimal equivalent.
        /// </summary>
        /// <param name="val">The value to be converted</param>
        /// <returns>The converted value</returns>
        public static decimal ParseDecimal(object val)
        {
            decimal valDecimal = 0;
            try
            {
                valDecimal = StringUtils.ParseDecimal(val);
                return valDecimal;
            }
            catch (Exception ex)
            {
                throw new Exception("PARSEDECIMAL(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Converts the object to its integer equivalent.
        /// </summary>
        /// <param name="val">The value to be converted</param>
        /// <returns>The converted value</returns>
        public static int ParseInteger(object val)
        {
            int valDecimal = 0;
            try
            {
                valDecimal = (int)StringUtils.ParseDecimal(val);
                return valDecimal;
            }
            catch (Exception ex)
            {
                throw new Exception("PARSEINTEGER(" + GetStr(val) + "): " + ex.Message);
            }
        }

        /// <summary>
        /// Converts the object to its date equivalent.
        /// </summary>
        /// <param name="val">The value to be converted</param>
        /// <returns>The converted value.</returns>
        public static DateTime ParseDate(object val)
        {
            DateTime valDate = DateTime.Today;
            try
            {
                valDate = DateTime.Parse(val.ToString());
                return valDate;
            }
            catch (Exception ex)
            {
                throw new Exception("PARSEDATE(" + GetStr(val) + "): " + ex.Message);
            }
        }
        #endregion

        #region "Session, Cookie, URL and other Functions"

        /// <summary>
        /// Return the value of the variable from the session.
        /// </summary>
        /// <param name="var">The name of the session variable</param>
        /// <returns>The session variable value.</returns>
        public static string Session(string var)
        {
            if (var == null || System.Web.HttpContext.Current.Session[var] == null) return string.Empty;
            return System.Web.HttpContext.Current.Session[var].ToString();
        }

        /// <summary>
        /// Return the value of the variable from the cookie.
        /// </summary>
        /// <param name="var">The name of the cookie variable</param>
        /// <returns>The cookie variable value.</returns>
        public static string Cookie(string var)
        {
            if (var == null || System.Web.HttpContext.Current.Request.Cookies[var] == null) return string.Empty;
            return System.Web.HttpContext.Current.Request.Cookies[var].Value;
        }

        /// <summary>
        /// Return the value of the variable from the cache.
        /// </summary>
        /// <param name="var">The name of the cache variable</param>
        /// <returns>The cache variable value.</returns>
        public static string Cache(string var)
        {
            if (var == null || System.Web.HttpContext.Current.Cache[var] == null) return string.Empty;
            return System.Web.HttpContext.Current.Cache[var].ToString();
        }

        /// <summary>
        /// Return the value of the URL parameter passed to the current page.
        /// </summary>
        /// <param name="var">The name of the URL variable</param>
        /// <returns>The URL variable value.</returns>
        public static string URL(string var)
        {
            string val = String.Empty;
            if (var == null) return string.Empty;

            val = System.Web.HttpContext.Current.Request.QueryString[var];

            // It is possible that the URL value is encrypted - so try to
            // decrypt. If we do not get an exception, then we know it was
            // encrypted - otherwise if we get an exception, then the value was
            // not encrypted in the first place, so return the actual value.
            try
            {
                val = Decrypt(val);
            }
            catch
            {
                // Ignore exception and return original value
            }


            if (KeyValue.IsXmlKey(val))
            {
                // URL values are typically passed as XML structures to handle composite keys.
                // If XML, then we will see if there is one element in the XML. If there is only one
                // element, we will return that element. Otherwise we will return the full XML.
                KeyValue key = KeyValue.XmlToKey(val);
                if (key.Count == 1)
                {
                    val = key.ColumnValue(0);
                }
            }

            return val;
        }

        /// <summary>
        /// Return the value of the URL parameter passed to the current page.
        /// If the URL is a Key Value pair, return the column value of the XML structure
        /// </summary>
        /// <param name="var">The name of the URL variable</param>
        /// <returns>The URL variable value.</returns>
        public static string URL(string var, string column)
        {
            string val = String.Empty;
            if (var == null) return string.Empty;

            val = System.Web.HttpContext.Current.Request.QueryString[var];

            // It is possible that the URL value is encrypted - so try to
            // decrypt. If we do not get an exception, then we know it was
            // encrypted - otherwise if we get an exception, then the value was
            // not encrypted in the first place, so return the actual value.
            try
            {
                val = Decrypt(val);
            }
            catch
            {
            // Ignore exception and return original value
            }

            if (KeyValue.IsXmlKey(val))
            {
                // URL values are typically passed as XML structures to handle composite keys.
                // If XML, then we will see if retrieve the value for the column name passed in
                // to the function.
                KeyValue key = KeyValue.XmlToKey(val);
                val = key.ColumnValueByName(column);
            }

            return val;
        }

        /// <summary>
        /// Return the value of the resource key. Only the application resources
        /// are returned by this function. Resources in the BaseClasses.resx file
        /// are not accessible through this function.
        /// </summary>
        /// <param name="var">The name of the resource key</param>
        /// <returns>The resource value.</returns>
        public static string Resource(string var)
        {
            if (var == null) return string.Empty;
            try
            {
                string appname = BaseClasses.Configuration.ApplicationSettings.Current.GetAppSetting(BaseClasses.Configuration.ApplicationSettings.ConfigurationKey.ApplicationName);
                object resObj = System.Web.HttpContext.GetGlobalResourceObject(appname, var);
                if (resObj != null)
                {
                    return resObj.ToString();
                }
            }
            catch
            {
                // If we cannot find the resource, simply return the variable that was passed-in.
            }
            return var;
        }

        /// <summary>
        /// Return the encrypted value of the string passed in.
        /// </summary>
        /// <param name="str">The string to encrypt</param>
        /// <returns>The encrypted value of the string.</returns>
        public static string Encrypt(string str)
        {
            if (str == null) return string.Empty;
            Crypto CheckCrypto = new Crypto();
            return CheckCrypto.Encrypt(str);
        }

        /// <summary>
        /// Return the decrypted value of the string passed in.
        /// </summary>
        /// <param name="str">The string to decrypt</param>
        /// <returns>The decrypted value of the string.</returns>
        public static string Decrypt(string str)
        {
            if (str == null) return string.Empty;
            Crypto CheckCrypto = new Crypto();
            return CheckCrypto.Decrypt(str);
        }

        /// <summary>
        /// Return the encrypted value of the string passed in.
        /// </summary>
        /// <param name="str">The string to encrypt</param>
        /// <returns>The encrypted value of the string.</returns>
        public static string EncryptData(string str)
        {
            if (str == null) return string.Empty;
            Crypto CheckCrypto = new Crypto();
            return CheckCrypto.Encrypt(str, false);
        }

        /// <summary>
        /// Return the decrypted value of the string passed in.
        /// </summary>
        /// <param name="str">The string to decrypt</param>
        /// <returns>The decrypted value of the string.</returns>
        public static string DecryptData(string str)
        {
            if (str == null) return string.Empty;
            Crypto CheckCrypto = new Crypto();
            string result = CheckCrypto.Decrypt(str, false);
            if (result == str || result == null || result == "")
                result = CheckCrypto.Encrypt(str, true);
            return result;
        }

        /// <summary>
        /// Return the currently logged in user id
        /// </summary>
        /// <returns>The user id of the currently logged in user.</returns>
        public static string UserId()
        {
            return BaseClasses.Utils.SecurityControls.GetCurrentUserID();
        }

        /// <summary>
        /// Return the currently logged in user ma,e
        /// </summary>
        /// <returns>The user name of the currently logged in user.</returns>
        public static string UserName()
        {
            return BaseClasses.Utils.SecurityControls.GetCurrentUserName();
        }

        /// <summary>
        /// Return the currently logged in user's roles. The roles are returned
        /// as a string array, so you can do something like 
        /// = If("Engineering" in Roles(), "Good", "Bad")
        /// </summary>
        /// <returns>The roles of the currently logged in user.</returns>
        public static string[] Roles {
	        get {
		        string rStr = BaseClasses.Utils.SecurityControls.GetCurrentUserRoles();
		        if ((rStr == null))
			        return new string[0];
		        return rStr.Split(';');
	        }
        }

        /// <summary>
        /// Return the value of the column from the currently logged in user's database 
        /// record. Allows access to any fields on the user record (e.g., email address)
        /// by simply doing something like UserRecord("EmailAddress")
        /// NOTE: This function ONLY applies to Database Role security. Does NOT
        /// apply to Active Directory, SharePoint, Windows Authentication or .NET Membership Roles
        /// </summary>
        /// <returns>The user record of the currently logged in user.</returns>
        public static object UserRecord(string colName)
        {
            IUserIdentityRecord rec = null;
            rec = BaseClasses.Utils.SecurityControls.GetUserRecord("");
            if (rec == null) return string.Empty;

            BaseColumn col = null;
            col = rec.TableAccess.TableDefinition.ColumnList.GetByCodeName(colName);
            if (col == null) return string.Empty;

            return rec.GetValue(col).Value;
        }
        #endregion

        #region "Database Access Functions"
        /// <summary>
        /// Return the value of the column from the database record specified by the key.  The
        /// key can be either an XML KeyValue structure or just a string that is the Id of the record.
        /// Only works for tables with a primary key or a virtual primary key.
        /// </summary>
        /// <returns>The value for the given field as an Object.</returns>
        public static object GetColumnValue(string tableName, decimal key, string fieldName)
        {
            return GetColumnValue(tableName, key.ToString(), fieldName);
        }


        /// <summary>
        /// Return the value of the column from the database record specified by the key.  The
        /// key can be either an XML KeyValue structure or just a string that is the Id of the record.
        /// Only works for tables with a primary key or a virtual primary key.
        /// </summary>
        /// <returns>The value for the given field as an Object.</returns>
        public static object GetColumnValue(string tableName, string key, string fieldName)
        {
            // Find a specific value from the database for the given record.
            PrimaryKeyTable bt = null;
            bt = (PrimaryKeyTable)DatabaseObjects.GetTableObject(tableName);
            if (bt == null)
            {
                throw new Exception("GETCOLUMNVALUE(" + tableName + ", " + key + ", " + fieldName + "): " + Resource("Err:NoRecRetrieved"));
            }

            IRecord rec = null;
            try
            {
                // Always start a transaction since we do not know if the calling function did.
                rec = bt.GetRecordData(key, false);
            }
            catch
            {
            }
            if (rec == null)
            {
                throw new Exception("GETCOLUMNVALUE(" + tableName + ", " + key + ", " + fieldName + "): " + Resource("Err:NoRecRetrieved"));
            }

            BaseColumn col = bt.TableDefinition.ColumnList.GetByCodeName(fieldName);
            if (col == null)
            {
                throw new Exception("GETCOLUMNVALUE(" + tableName + ", " + key + ", " + fieldName + "): " + Resource("Err:NoRecRetrieved"));
            }

            // The value can be null.  In this case, return an empty string since
            // that is an acceptable value.
            ColumnValue fieldData = rec.GetValue(col);
            if (fieldData == null)
            {
                return string.Empty;
            }

            return fieldData.Value;
        }

        /// <summary>
        /// Return an array of values from the database.  The values returned are DISTINCT values.
        /// For example, GetColumnValues("Employees", "City") will return a list of all Cities
        /// from the Employees table. There will be no duplicates in the list.
        /// You can use the IN operator to compare the values.  You can also use the resulting array to display
        /// such as String.Join(", ", GetColumnValues("Employees", "City")
        /// to display: New York, Chicago, Los Angeles, San Francisco
        /// </summary>
        /// <returns>An array of values for the given field as an Object.</returns>
        public static string[] GetColumnValues(string tableName, string fieldName)
        {
            return GetColumnValues(tableName, fieldName, string.Empty);
        }

        /// <summary>
        /// Return an array of values from the database.  The values returned are DISTINCT values.
        /// For example, GetColumnValues("Employees", "City") will return a list of all Cities
        /// from the Employees table. There will be no duplicates in the list.
        /// This function adds a Where Clause.  So you can say something like "Country = 'USA'" and in this
        /// case only cities in the US will be returned.
        /// You can use the IN operator to compare the values.  You can also use the resulting array to display
        /// such as String.Join(", ", GetColumnValues("Employees", "City", "Country = 'USA'")
        /// to display: New York, Chicago, Los Angeles, San Francisco
        /// </summary>
        /// <returns>An array of values for the given field as an Object.</returns>
        public static string[] GetColumnValues(string tableName, string fieldName, string whereStr)
        {
            // Find the 
            PrimaryKeyTable bt = null;
            bt = (PrimaryKeyTable)DatabaseObjects.GetTableObject(tableName);
            if (bt == null)
            {
                throw new Exception("GETCOLUMNVALUES(" + tableName + ", " + fieldName + ", " + whereStr + "): " + Resource("Err:NoRecRetrieved"));
            }

            BaseColumn col = bt.TableDefinition.ColumnList.GetByCodeName(fieldName);
            if (col == null)
            {
                throw new Exception("GETCOLUMNVALUES(" + tableName + ", " + fieldName + ", " + whereStr + "): " + Resource("Err:NoRecRetrieved"));
            }

            string[] values = null;

            try
            {
                // Always start a transaction since we do not know if the calling function did.
                SqlBuilderColumnSelection sqlCol = new SqlBuilderColumnSelection(false, true);
                sqlCol.AddColumn(col);

                WhereClause wc = new WhereClause();
                if (!(whereStr == null) && whereStr.Trim().Length > 0)
                {
                    wc.iAND(whereStr);
                }
                BaseClasses.Data.BaseFilter join = null; 
                values = bt.GetColumnValues(sqlCol, join, wc.GetFilter(), null, null, BaseTable.MIN_PAGE_NUMBER, BaseTable.MAX_BATCH_SIZE);
            }
            catch
            {
            }

            // The value can be null.  In this case, return an empty array since
            // that is an acceptable value.
            if (values == null)
            {
                values = new string[0];
            }


            return values;
        }
        #endregion

        #region "Private Convenience Functions"
        /// <summary>
        /// Convert an object to string
        /// </summary>
        /// <param name="str">The input to be converted</param>
        /// <returns>The input to be converted.</returns>
        private static string GetStr(object str)
        {
            if (str == null) return string.Empty;
            return str.ToString();
        }

        #endregion


    }
}





